﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ICSharpCode.AvalonEdit;
using System.Windows;
using Microsoft.Xaml.Behaviors;

namespace UiDesktopApp2.Helpers;

public sealed class AvalonEditBehaviour : Behavior<TextEditor>
{
    //依赖属性绑定
    public static readonly DependencyProperty CodeTextProperty =
    DependencyProperty.Register("CodeText",
                                typeof(string),
                                typeof(AvalonEditBehaviour),
                                new FrameworkPropertyMetadata(default(string),
                                                              FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                                                              PropertyChangedCallback));

    public string CodeText
    {
        get => (string)GetValue(CodeTextProperty);
        set => SetValue(CodeTextProperty, value);
    }

    protected override void OnAttached()
    {
        base.OnAttached();
        if (AssociatedObject != null)
            AssociatedObject.TextChanged += AssociatedObjectOnTextChanged;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        if (AssociatedObject != null)
            AssociatedObject.TextChanged -= AssociatedObjectOnTextChanged;
    }

    private void AssociatedObjectOnTextChanged(object? sender, EventArgs eventArgs)
    {
        if (sender is TextEditor textEditor)
        {
            if (textEditor.Document != null)
                CodeText = textEditor.Document.Text;
        }
    }

    private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
    {
        var behavior = dependencyObject as AvalonEditBehaviour;
        if (behavior?.AssociatedObject != null)
        {
            var editor = behavior.AssociatedObject;
            if (editor.Document != null)
            {
                var caretOffset = editor.CaretOffset;
                editor.Document.Text = dependencyPropertyChangedEventArgs.NewValue.ToString();
                if (caretOffset <= editor.Document.Text?.Length) editor.CaretOffset = caretOffset;
            }
        }
    }
}